package org.edu.zzu.health_report.job;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.edu.zzu.health_report.domain.Record;
import org.edu.zzu.health_report.domain.User;
import org.edu.zzu.health_report.service.RecordService;
import org.edu.zzu.health_report.service.UserService;
import org.edu.zzu.health_report.util.HttpClientUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
 * @author gaopeng
 * @date 2021/11/8
 **/
@Component
@Slf4j
public class ReportJob {

    @Autowired
    private UserService userService;

    @Autowired
    private RecordService recordService;

    private static final String LOGINURL = "https://jksb.v.zzu.edu.cn/vls6sss/zzujksb.dll/login";
    private static final String LOGREGEX = "location=\"(\\S+)\"";
    private static final String FILLINBYMYSELFURL = "https://jksb.v.zzu.edu.cn/vls6sss/zzujksb.dll/jksb";
    private static final Pattern LOGINPARRERN = Pattern.compile(LOGREGEX);
    private static final String CHECKSTR = "审核";
    
    //@Scheduled(cron = "0 28 14 * * ?")
    @Scheduled(cron = "0 1,31 0,1,2,3,4,5,6,7,8,9 * * ?")
    public void reportJob(){
        long today = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).toInstant(ZoneOffset.of("+8")).toEpochMilli();
        List<User> unReportUsers = unReportUserQuery(today);
        log.info("数据库解析，一共{}个用户尚未打卡",unReportUsers.size());
        for (User unReportUser : unReportUsers) {
            log.info("-- {} -- {} -- 打卡开始",unReportUser.getUserId(),unReportUser.getName());
            log.debug("user={}", JSON.toJSONString(unReportUser));
            login(unReportUser);
            try {
                Thread.sleep(4000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }

    public List<User> unReportUserQuery(Long day){
        List<User> all = userService.getAll();
        log.info("数据库解析，一共{}个用户",all.size());
        List<User> unReportList = all.stream().filter(user -> {
            Record record = recordService.getByDate(user.getUserId(), day);
            //已打卡
            return record == null || !"1".equals(record.getRes());
        }).collect(Collectors.toList());
        return unReportList;
    }
    
    private void login(User user){
        //通过账号密码登录
        Map<String,String> loginMap=new HashMap<>(2);
        loginMap.put("uid",user.getUserId());
        loginMap.put("upw",user.getUserPwd());
        log.info("-- {} -- {} -- 登录",user.getUserId(),user.getName());
        String loginHtml = HttpClientUtil.doPost(LOGINURL, loginMap);
        log.info("-- {} -- {} -- 登录页面解析开始",user.getUserId(),user.getName());
        Matcher matcher = LOGINPARRERN.matcher(loginHtml);
        if (matcher.find()) {
            log.info("-- {} -- {} -- 登录页面解析成功",user.getUserId(),user.getName());
            // 疫情打卡跳转页处理（信息获取）
            String str = matcher.group();
            // https://jksb.v.zzu.edu.cn/vls6sss/zzujksb.dll/first6?
            String newUrl = str.substring(10,str.length()-1);
            String paramsContent = newUrl.substring(53);
            String[] paramsStr = paramsContent.split("&");
            String ptopid = paramsStr[0].substring(7);
            String sid = paramsStr[1].substring(7);
            log.info("-- {} -- {} -- 疫情打卡跳转页解析",user.getUserId(),user.getName());

            // 二、疫情打卡首页处理
            Map<String,String> clickMap = new HashMap<>(8);
            // 每日填报
            clickMap.put("day6","b");
            // 隐藏上送字段
            clickMap.put("did","1");
            clickMap.put("door","");
            clickMap.put("men6","a");
            clickMap.put("ptopid",ptopid);
            clickMap.put("sid",sid);
            HttpClientUtil.doPost(FILLINBYMYSELFURL, clickMap);
            log.info(LocalDateTime.now() + "-- {} -- {} -- 疫情打卡首页处理",user.getUserId(),user.getName());

            // 三、疫情打卡提交页处理
            // 构造用户信息（上送字段）
            Map<String,String> importMap = new HashMap<>(32);
            // 1、您今天是否有发热症状
            importMap.put("myvs_1", user.getMyvs1());
            // 2、您今天是否有咳嗽症状
            importMap.put("myvs_2", user.getMyvs2());
            // 3、您今天是否有乏力或轻微乏力症状
            importMap.put("myvs_3", user.getMyvs3());
            // 4、您今天是否有鼻塞、流涕、咽痛或者腹泻等症状
            importMap.put("myvs_4", user.getMyvs4());
            // 5、您今天是否被所在地医疗机构确定为确诊病例?
            importMap.put("myvs_5",user.getMyvs5());
            // 6、您今天是否被所在地医疗机构确定为疑似病例?
            importMap.put("myvs_6",user.getMyvs6());
            // 7、您今天是否被所在地政府或医疗卫生部门确定为密切接触者?
            importMap.put("myvs_7",user.getMyvs7());
            // 8、您今天是否被所在地医疗机构进行院内隔离观察治疗?
            importMap.put("myvs_8",user.getMyvs8());
            // 9、您今天是否被要求在政府集中隔离点进行隔离观察?
            importMap.put("myvs_9",user.getMyvs9());
            // 10、您今天是否被要求在政府集中隔离点进行隔离观察?
            importMap.put("myvs_10",user.getMyvs10());
            // 11、所在小区（村）是否有确诊病例?(以当地政府公开信息为准)
            importMap.put("myvs_11",user.getMyvs11());
            // 12、共同居住人是否有确诊病例?
            importMap.put("myvs_12",user.getMyvs12());
            //健康码颜色
            importMap.put("myvs_13", user.getMyvs13());
            // 13、当前居住地：
            // 省份（自治区）
            importMap.put("myvs_13a", user.getMyvs13a());
            // 地市
            importMap.put("myvs_13b", user.getMyvs13b());
            // 具体地址
            importMap.put("myvs_13c", user.getMyvs13c());
            // 14、您是否为当日返郑人员
            importMap.put("myvs_24", user.getMyvs24());
            //当前疫苗接种情况
            importMap.put("myvs_26", user.getMyvs26());
            //地理位置
            importMap.put("memo22",user.getMemo22());

            // 隐藏字段
            importMap.put("did","2");
            importMap.put("door","");
            importMap.put("men6","a");
            importMap.put("day6","b");
            importMap.put("sheng6","");
            importMap.put("shi6","");
            importMap.put("fun3","");
            importMap.put("jingdu","0.000000");
            importMap.put("weidu","0.000000");
            importMap.put("ptopid", ptopid);
            importMap.put("sid", sid);
            String s = HttpClientUtil.doPost(FILLINBYMYSELFURL, importMap);
            log.info("-- {} -- {} -- 疫情确认页处理",user.getUserId(),user.getName());
            //System.out.println(importMap.get("myvs_13"));
            Record record=new Record();
            long today = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).toInstant(ZoneOffset.of("+8")).toEpochMilli();
            record.setCreateDate(today);
            record.setModifyDate(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
            record.setUserId(user.getUserId());
            record.setSend("0");
            if(s.contains(CHECKSTR)) {
                log.info("-- {} -- {} -- 疫情打卡任务成功",user.getUserId(),user.getName());
                record.setRes("1");
                if (recordService.save(record)) {
                    log.info("-- {} -- {} -- 疫情打卡任务成功记录插入完成",user.getUserId(),user.getName());
                } else{
                    log.error("-- {} -- {} -- 疫情打卡任务成功记录插入失败",user.getUserId(),user.getName());
                }
            } else {
                log.error("-- {} -- {} -- 疫情打卡任务失败",user.getUserId(),user.getName());
                record.setRes("0");
                record.setReason(s);
                if (recordService.save(record)) {
                    log.info("-- {} -- {} -- 疫情打卡任务失败记录插入完成",user.getUserId(),user.getName());
                } else{
                    log.error("-- {} -- {} -- 疫情打卡任务失败记录插入失败",user.getUserId(),user.getName());
                }
            }
        } else {
            // 解析失败，则打卡结束。
            log.error("-- {} -- {} -- 登录失败,reason={}",user.getUserId(),user.getName(),loginHtml);
        }
    }

    public static void main(String[] args) {
        LocalDateTime start = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        long epochSecond = start.toEpochSecond(ZoneOffset.of("+8"));
        long epochMilli = start.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        System.out.println(epochMilli);
    }
}
